package com.csvw.skr.basic.resource;

import com.csvw.skr.basic.core.JobType;
import com.csvw.skr.basic.entity.LoginLog;
import com.csvw.skr.basic.entity.SystemVersion;
import com.csvw.skr.basic.entity.User;
import com.csvw.skr.basic.service.RbacService;
import com.csvw.skr.console.service.OrganizationService;

import com.webonn.frame.core.OAuthPrincipal;
import com.webonn.frame.core.TokenController;
import com.webonn.frame.db.MyDao;
import com.webonn.frame.util.APIResultBuilder;
import com.webonn.frame.util.MyStringUtil;
import com.webonn.frame.util.PasswordUtils;
import com.webonn.frame.util.SmsController;

import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
@PermitAll
@RestController
@RequestMapping("/")
public class AuthResource {

    @Autowired
    private RbacService rbacService;
    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private MyDao myDao;

    @RequestMapping(value="/version/{type}", method= RequestMethod.GET)
    public Response getCurrentVersion(@PathVariable String type) {
        String sql = "select * from csvw_skr_system_version where type = ? order by id desc limit 1 ";
        List<SystemVersion> result = myDao.list(sql, SystemVersion.class, new Object[]{type});
        if (result != null && result.size() > 0)
            return APIResultBuilder.CREATED((result.get(0)));
        return APIResultBuilder.CREATED(new SystemVersion());
    }


    @RequestMapping(value="/verification", method= RequestMethod.POST)
    public Response sendCode(@NotEmpty Map<String, String> doc) {
        String empno = doc.getOrDefault("empno", null);
        String email = doc.getOrDefault("email", null);
        String phone = doc.getOrDefault("phone", null);

        if (MyStringUtil.isNullOrEmpty(empno)) {
            return APIResultBuilder.INVALID_REQUEST("缺少员工号参数");
        }
        if (MyStringUtil.isNullOrEmpty(email)) {
            return APIResultBuilder.INVALID_REQUEST("缺少员工邮箱参数");
        }
        if (MyStringUtil.isNullOrEmpty(phone)) {
            return APIResultBuilder.INVALID_REQUEST("缺少手机号参数");
        }

        User user = rbacService.getUser(empno);
        if (user == null || !phone.equalsIgnoreCase(user.getPhone()) || !email.equalsIgnoreCase(user.getEmail())) {
            return APIResultBuilder.UnprocesableEntity("员工信息不匹配");
        }

        //发送验证码
        SmsController sms = SmsController.getInstance();
        if (sms.sendcode(phone)) {
            Map<String, Object> result = new HashMap<>();
            result.put("result", Objects.nonNull(phone));
            return APIResultBuilder.CREATED(result);
        } else {
            return APIResultBuilder.INTERNAL_SERVER_ERROR("发送验证码失败，请联系管理员");
        }
    }


    @RequestMapping(value="/register", method= RequestMethod.POST)
    public Response register(Map<String, String> doc) {
        String empno = doc.getOrDefault("empno", null);
        String email = doc.getOrDefault("email", null);
        String phone = doc.getOrDefault("phone", null);
        String password = doc.getOrDefault("password", null);
        String code = doc.getOrDefault("code", null);

        if (MyStringUtil.isNullOrEmpty(empno)) {
            return APIResultBuilder.INVALID_REQUEST("缺少员工号参数");
        }
        if (MyStringUtil.isNullOrEmpty(email)) {
            return APIResultBuilder.INVALID_REQUEST("缺少员工邮箱参数");
        }
        if (MyStringUtil.isNullOrEmpty(phone)) {
            return APIResultBuilder.INVALID_REQUEST("缺少手机号参数");
        }
        if (MyStringUtil.isNullOrEmpty(password)) {
            return APIResultBuilder.INVALID_REQUEST("缺少密码参数");
        }
        if (MyStringUtil.isNullOrEmpty(code)) {
            return APIResultBuilder.INVALID_REQUEST("缺少号验证码参数");
        }

        int codeint = Integer.parseInt(code);
        if (!SmsController.getInstance().authcode(codeint, phone)) {
            return APIResultBuilder.UnprocesableEntity("验证码错误");
        }

        User user_old = rbacService.getUser(empno);
        if (!phone.equalsIgnoreCase(user_old.getPhone()) || !email.equalsIgnoreCase(user_old.getEmail())) {
            return APIResultBuilder.UnprocesableEntity("员工信息不匹配");
        }

        if (user_old.isActive()) {
            return APIResultBuilder.Forbidden("该用户已经注册");
        }
        Date registerTime = new Date();
        user_old.setCreated(registerTime);
        user_old.setActive(true);
        user_old.setPassword(PasswordUtils.enpassword(password));
        user_old.setUpdated(registerTime);

        if (Objects.nonNull(rbacService.updateUser(user_old))) {
            return APIResultBuilder.CREATED(rbacService.getUserByUserName(empno));
        } else {
            return APIResultBuilder.INTERNAL_SERVER_ERROR("注册失败，请联系管理员");
        }
    }

    @PermitAll
    @RequestMapping(value="/userInfo/{userId}", method= RequestMethod.GET)
    public Response getUser( OAuthPrincipal principal, @PathVariable String userId) {
        /*if(Objects.isNull(principal.getName()) || !principal.getName().equalsIgnoreCase(userId)){
            return APIResultBuilder.Forbidden("不可查看他人信息");
		}*/
        Map<String, Object> result = rbacService.getUserByUserName(userId);
        if (Objects.nonNull(result)) {
            result.put("organizationName", organizationService.getOrganizationInfo((String) result.get("organization")));
            return APIResultBuilder.OK(result);
        } else {
            return APIResultBuilder.NOT_FOUND("用户未找到");
        }
    }

    @PermitAll
    @RequestMapping(value="/userId", method= RequestMethod.GET)
    public Response getUser( OAuthPrincipal principal) {
        Map<String, Object> result = rbacService.getUserByUserName(principal.getName());
        if (Objects.nonNull(result)) {
            return APIResultBuilder.OK(result);
        } else {
            return APIResultBuilder.NOT_FOUND("用户未找到");
        }
    }

    @PermitAll
    /*@PATCH
    @Path("/password")*/
    @RequestMapping(value="/password", method= RequestMethod.PATCH)
    public Response updateUserPassword( OAuthPrincipal principal, @NotEmpty Map<String, String> doc) {
        String empno = doc.getOrDefault("empno", null);
        String oldPassword = doc.getOrDefault("oldPassword", null);
        String password = doc.getOrDefault("password", null);

        if (MyStringUtil.isNullOrEmpty(principal.getName()) || !principal.getName().equalsIgnoreCase(empno)) {
            return APIResultBuilder.Forbidden("不可修改他人密码");
        }

        if (MyStringUtil.isNullOrEmpty(empno)) {
            return APIResultBuilder.INVALID_REQUEST("缺少用户登录名参数");
        }
        if (MyStringUtil.isNullOrEmpty(oldPassword)) {
            return APIResultBuilder.INVALID_REQUEST("缺少原始密码参数");
        }
        if (MyStringUtil.isNullOrEmpty(password)) {
            return APIResultBuilder.INVALID_REQUEST("缺少新密码参数");
        }

        User oldUser = rbacService.getUser(empno);
        if (PasswordUtils.equalsPassword(oldPassword, oldUser.getPassword())) {
            Map<String, Object> result = new HashMap<>();
            result.put("result", Objects.nonNull(rbacService.updateUserPassword(empno, password)));
            return APIResultBuilder.CREATED(result);
        } else {
            return APIResultBuilder.Forbidden("用户原始密码错误");
        }
    }

    @RequestMapping(value="/forget", method= RequestMethod.PATCH)
    public Response forgetPassword(@NotEmpty Map<String, String> doc) {
        String empno = doc.getOrDefault("empno", null);
        String email = doc.getOrDefault("email", null);
        String phone = doc.getOrDefault("phone", null);
        String code = doc.getOrDefault("code", null);
        String password = doc.getOrDefault("password", null);

        if (MyStringUtil.isNullOrEmpty(empno)) {
            return APIResultBuilder.INVALID_REQUEST("缺少员工号参数");
        }
        if (MyStringUtil.isNullOrEmpty(email)) {
            return APIResultBuilder.INVALID_REQUEST("缺少员工邮箱参数");
        }
        if (MyStringUtil.isNullOrEmpty(phone)) {
            return APIResultBuilder.INVALID_REQUEST("缺少手机号参数");
        }
        if (MyStringUtil.isNullOrEmpty(password)) {
            return APIResultBuilder.INVALID_REQUEST("缺少密码参数");
        }
        if (MyStringUtil.isNullOrEmpty(code)) {
            return APIResultBuilder.INVALID_REQUEST("缺少号验证码参数");
        }
        int codeint = Integer.parseInt(code);
        if (!SmsController.getInstance().authcode(codeint, phone)) {
            return APIResultBuilder.Forbidden("验证码错误");
        }
        User oldUser = rbacService.getUser(empno);
        if (!phone.equalsIgnoreCase(oldUser.getPhone()) || !email.equalsIgnoreCase(oldUser.getEmail())) {
            return APIResultBuilder.UnprocesableEntity("员工信息不匹配");
        }
        Map<String, Object> result = new HashMap<>();
        result.put("result", Objects.nonNull(rbacService.updateUserPassword(empno, password)));
        return APIResultBuilder.CREATED(result);
    }

    @RequestMapping(value="/login/log", method= RequestMethod.POST)
    public Response loginLog(LoginLog entity) {
        LoginLog result = rbacService.addLoginLog(entity);
        if (result != null)
            return APIResultBuilder.CREATED(result);
        return APIResultBuilder.INTERNAL_SERVER_ERROR("操作失败");
    }

    @RequestMapping(value="/login", method= RequestMethod.POST)
    public Response login(@RequestBody Map<String, String> doc) {

        String userId = doc.getOrDefault("user", null);
        String password = doc.getOrDefault("password", null);

        if (MyStringUtil.isNullOrEmpty(userId)) {
            return APIResultBuilder.INVALID_REQUEST("缺少登录用户名参数");
        }
        if (MyStringUtil.isNullOrEmpty(password)) {
            return APIResultBuilder.INVALID_REQUEST("缺少密码参数");
        }

        User result = rbacService.checkUser(userId);
        if (Objects.isNull(result)) {
            return APIResultBuilder.NOT_FOUND("登录名错误");
        }
        if (result.isActive() && PasswordUtils.equalsPassword(password, result.getPassword())) {
            String token = TokenController.getInstance().generateTokenForEntity(result.getEmpno());
            Map<String, String> map = new HashMap<>();
            map.put("token", token);
            map.put("userId", result.getEmpno());
            return APIResultBuilder.CREATED(map);
        } else {
            return APIResultBuilder.Forbidden("验证失败，用户或密码错误");
        }
    }

    //上线后需要去掉
    @RolesAllowed({JobType.ADMINISTRATOR})
    @RequestMapping(value="/delete/{userId}", method= RequestMethod.GET)
    public Response login(@PathVariable String userId) {
        User result = rbacService.getUser(userId);
        result.setActive(false);
        result.setPassword(null);
        return APIResultBuilder.OK(rbacService.updateUser(result));
    }

    @RequestMapping(value="/logout", method= RequestMethod.GET)
    public Response logout( OAuthPrincipal principal) {
        Map<String, Object> result = new HashMap<>();
        if (Objects.isNull(principal)) {
            result.put("result", "已退出");
        } else {
            TokenController.getInstance().revokeTokenForEntity(principal.getName(), principal.getToken());
            result.put("result", "退出成功");
        }
        return APIResultBuilder.OK(result);
    }

    // 验证token是否正确
    @RequestMapping(value="/valid/{token}/logout", method= RequestMethod.GET)
    public Response valid(@PathVariable String token) {
        return APIResultBuilder.OK(TokenController.getInstance().isValidToken(token));
    }
}
